﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using ShadowCommando.Game.Elements;
using ShadowCommando.Game.Elements.Bonus;
using ShadowCommando.Game.GameGraphics.Resources;
using ShadowCommando.Game.Elements.Obstacle;


namespace ShadowCommando.Game.GameGraphics
{
    class GameGraphic
    {
        private Color tranparencyColor;
        private  Dictionary<EnemyId, Bitmap> enemyDictionary;
        private Dictionary<HeroId, Bitmap> heroDictionary;
        private Dictionary<BulletId, Bitmap> bulletDictionary;
        private Dictionary<ObstacleId, Bitmap> obstacleDictionary;
        private Dictionary<BonusId, Bitmap> bonusDictionary;
        private Dictionary<BulletId, List<Bitmap>> bulletAnimationDictionary;
        private Dictionary<ObstacleId, List<Bitmap>> obstacleAnimationDictionary;
        private Dictionary<BulletId, Bitmap> weaponDictionary;
        private Dictionary<DeadId, Bitmap> deadDictionary;

        public GameGraphic()
        {
            tranparencyColor = GraphicSettings.Default.TransparencyColor;
            InitBonus();
            InitBullet();
            InitBulletAnimation();
            InitEnemy();
            InitHero();
            InitObstacle();
            InitDead();
            InitObstacleAnimtion();
        }
        private void InitEnemy()
        {
            enemyDictionary = new Dictionary<EnemyId, Bitmap>();
            enemyDictionary.Add(EnemyId.DroidB1, EnemyGraphics.EnemyTestImage);
            enemyDictionary.Add(EnemyId.DroidB2,EnemyGraphics.DroidB2);
            enemyDictionary.Add(EnemyId.Droideka, EnemyGraphics.DroidekaImage);
            enemyDictionary.Add(EnemyId.Trash, EnemyGraphics.TrashImage);
        }
        private void InitHero()
        {
            heroDictionary=new Dictionary<HeroId, Bitmap>();
            
            heroDictionary.Add(HeroId.Test,HeroGraphics.HeroImage1);
        }
        private void InitBullet()
        {
            bulletDictionary=new Dictionary<BulletId, Bitmap>();

            bulletDictionary.Add(BulletId.Check, BulletGraphics.HeavyLaserImage1);
             bulletDictionary.Add(BulletId.HeavyLaser ,BulletGraphics.HeavyLaserImage1);
            bulletDictionary.Add(BulletId.Bomb,BulletGraphics.BombImage);
        //    bulletDictionary.Add(BulletId.Laser, BulletGraphics.DroidB2BulletImage);

            bulletDictionary.Add(BulletId.Flechette, BulletGraphics.FlechetteImage);
            bulletDictionary.Add(BulletId.Laser,BulletGraphics.LaserImage);
        }
        private void InitDead()
        {
            deadDictionary=new Dictionary<DeadId, Bitmap>();
            deadDictionary.Add(DeadId.EnemyId,EnemyGraphics.TrashImage);
            deadDictionary.Add(DeadId.Tree, ObstacleGraphics.DeadTree);
        }
        private void InitObstacle()
        {
            obstacleDictionary=new Dictionary<ObstacleId, Bitmap>();
            obstacleDictionary.Add(ObstacleId.Building,ObstacleGraphics.BuildingImage);
            obstacleDictionary.Add(ObstacleId.Building2, ObstacleGraphics.Building2);
            obstacleDictionary.Add(ObstacleId.Wall,ObstacleGraphics.WallImage);
            obstacleDictionary.Add(ObstacleId.Factory,ObstacleGraphics.FactoryImage);
            obstacleDictionary.Add(ObstacleId.Laboratory,ObstacleGraphics.LaboratoryImage);
            obstacleDictionary.Add(ObstacleId.Lake1,ObstacleGraphics.LakeImage1);
            obstacleDictionary.Add(ObstacleId.Leaf1,ObstacleGraphics.LeafImage1);
            obstacleDictionary.Add(ObstacleId.Tree1, ObstacleGraphics.TreeImage3);
            obstacleDictionary.Add(ObstacleId.Tree2, ObstacleGraphics.TreeImage4);
            obstacleDictionary.Add(ObstacleId.Tree3, ObstacleGraphics.TreeImage5);
            obstacleDictionary.Add(ObstacleId.Tree4, ObstacleGraphics.TreeImage6);
            obstacleDictionary.Add(ObstacleId.Tree5, ObstacleGraphics.TreeImage1);
            obstacleDictionary.Add(ObstacleId.Tree6, ObstacleGraphics.TreeImage2);
            obstacleDictionary.Add(ObstacleId.Tree7, ObstacleGraphics.TreeImage7);
            obstacleDictionary.Add(ObstacleId.Palm1,ObstacleGraphics.PalmImage1);
            obstacleDictionary.Add(ObstacleId.Palm2, ObstacleGraphics.PalmImage2);
            obstacleDictionary.Add(ObstacleId.Palm3, ObstacleGraphics.PalmImage3);
            obstacleDictionary.Add(ObstacleId.Palm4, ObstacleGraphics.PalmImage4);
            obstacleDictionary.Add(ObstacleId.Palm5, ObstacleGraphics.PalmImage5);
            obstacleDictionary.Add(ObstacleId.Palm6, ObstacleGraphics.PalmImage6);

            obstacleDictionary.Add(ObstacleId.Branch1, ObstacleGraphics.BranchImage1);
            obstacleDictionary.Add(ObstacleId.Branch2, ObstacleGraphics.BranchImage2);
            obstacleDictionary.Add(ObstacleId.Branch3, ObstacleGraphics.BranchImage3);
            obstacleDictionary.Add(ObstacleId.Branch4, ObstacleGraphics.BranchImage4);

            obstacleDictionary.Add(ObstacleId.Ice1, ObstacleGraphics.IceImage1);
            obstacleDictionary.Add(ObstacleId.Ice2, ObstacleGraphics.IceImage2);
            obstacleDictionary.Add(ObstacleId.Ice3, ObstacleGraphics.IceImage3);
            obstacleDictionary.Add(ObstacleId.Ice4, ObstacleGraphics.IceImage4);
            obstacleDictionary.Add(ObstacleId.Ice5, ObstacleGraphics.IceImage5);

            obstacleDictionary.Add(ObstacleId.Snow1, ObstacleGraphics.SnowImage1);
            obstacleDictionary.Add(ObstacleId.Snow2, ObstacleGraphics.SnowImage2);

            obstacleDictionary.Add(ObstacleId.SnowTree1, ObstacleGraphics.SnowTreeImage1);


            obstacleDictionary.Add(ObstacleId.Stone1, ObstacleGraphics.StoneImage1);
            obstacleDictionary.Add(ObstacleId.Stone2, ObstacleGraphics.StoneImage2);
            obstacleDictionary.Add(ObstacleId.Stone3, ObstacleGraphics.StoneImage3);
            obstacleDictionary.Add(ObstacleId.Stone4, ObstacleGraphics.StoneImage4);
            obstacleDictionary.Add(ObstacleId.Stone5, ObstacleGraphics.StoneImage5);
            obstacleDictionary.Add(ObstacleId.Stone6, ObstacleGraphics.StoneImage6);

            obstacleDictionary.Add(ObstacleId.Rock1, ObstacleGraphics.RockImage1);
            obstacleDictionary.Add(ObstacleId.Rock2, ObstacleGraphics.RockImage2);

            obstacleDictionary.Add(ObstacleId.Dune1, ObstacleGraphics.DuneImage1);
        }
        private void InitBonus()
        {
            bonusDictionary=new Dictionary<BonusId, Bitmap>();
            bonusDictionary.Add(BonusId.Ammuntion,BonusGraphics.AmmuntionImage);
            bonusDictionary.Add(BonusId.Armor,BonusGraphics.ArmorImage);
            bonusDictionary.Add(BonusId.MedicalKit,BonusGraphics.MedicalKitImage);

        }
        private void InitWeapon()
        {
            weaponDictionary=new Dictionary<BulletId, Bitmap>();
            weaponDictionary.Add(BulletId.Laser, WeaponGraphics.Laser);
            weaponDictionary.Add(BulletId.Flechette, WeaponGraphics.Laser);
            weaponDictionary.Add(BulletId.HeavyLaser, WeaponGraphics.Laser);
            weaponDictionary.Add(BulletId.Bomb, WeaponGraphics.Laser);
        }
        private void InitBulletAnimation()
        {
            bulletAnimationDictionary=new Dictionary<BulletId, List<Bitmap>>();
            List<Bitmap>list=new List<Bitmap>();

            list.Add(AnimationGraphics.BuildingExplosion1);
            list.Add(AnimationGraphics.BuildingExplosion2);
            list.Add(AnimationGraphics.BuildingExplosion3);
            list.Add(AnimationGraphics.BuildingExplosion4);
            list.Add(AnimationGraphics.BuildingExplosion5);
            list.Add(AnimationGraphics.BuildingExplosion6);
            list.Add(AnimationGraphics.BuildingExplosion7);
            list.Add(AnimationGraphics.BuildingExplosion8);
            list.Add(AnimationGraphics.BuildingExplosion9);
            list.Add(AnimationGraphics.BuildingExplosion10);
            list.Add(AnimationGraphics.BuildingExplosion11);
            list.Add(AnimationGraphics.BuildingExplosion12);
            bulletAnimationDictionary.Add(BulletId.Bomb, list);
        }
        private void InitObstacleAnimtion()
        {
            obstacleAnimationDictionary=new Dictionary<ObstacleId, List<Bitmap>>();
            List<Bitmap> list = new List<Bitmap>();
            list.Add(AnimationGraphics.Explosion1);
            list.Add(AnimationGraphics.Explosion2);
            list.Add(AnimationGraphics.Explosion3);
            list.Add(AnimationGraphics.Explosion4);
            list.Add(AnimationGraphics.Explosion5);
            list.Add(AnimationGraphics.Explosion6);
            list.Add(AnimationGraphics.Explosion7);
            list.Add(AnimationGraphics.Explosion8);
            obstacleAnimationDictionary.Add(ObstacleId.Building,list);
        }
        /// <summary>
        /// Tworzy przezroczysty obrazek
        /// </summary>
        /// <param name="image">Obrazek</param>
        /// <param name="color">Kolor który ma zostać być przezroczysty</param>
        /// <returns></returns>
        public Bitmap MakeTransparent(Bitmap image, Color color)
        {
            image.MakeTransparent(color);
            return image;
        }

        public Bitmap MakeTransparent(Bitmap image)
        {
            Color color = tranparencyColor;
            image.MakeTransparent(color);
            return image;
        }
        /// <summary>
        /// Obróć obrazek
        /// </summary>
        /// <param name="image">Obrazek</param>
        /// <param name="angle">Kąt</param>
        /// <returns>Obrócony obrazek</returns>
        private Bitmap RotateImage(Bitmap image, int angle)
        {
            Bitmap bitmap = new Bitmap(image.Width, image.Height);
            Graphics g = Graphics.FromImage(bitmap);
            g.TranslateTransform(image.Width / 2, image.Height / 2);
            g.RotateTransform(angle);
            g.TranslateTransform(-image.Width / 2, -image.Height / 2);
            g.DrawImage(image, new Point(0, 0));
            return bitmap;
        }
        /// <summary>
        /// Ustawia rozmiary elementu na podstawie przypisanego mu obrazka
        /// </summary>
        /// <param name="element">Element do ustawienia rozmiarów</param>
        public void SetElementSize(Element element)
        {
            Bitmap bitmap = GetImage(element);
            element.SetSize(bitmap.Width,bitmap.Height);
        }
        /// <summary>
        /// Pobiera obrazek z przpisanym mu ID
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public Bitmap GetImage(Element element)
        {
            if (element.IsAnimated)
                return GetAnimation(element);
            else
            {
                return GetBitmap((element));
            }
        }
       

        private Bitmap GetBitmap(Element element)
        {
            switch ((element.ElementId))
            {
                case ElementId.Hero:
                    {
                        return GetHeroImage(element);
                    }
                case ElementId.Enemy:
                    {
                        return GetEnemyImage(element);
                    }
                case ElementId.Bullet:
                    {
                        return GetBulletImage(element);
                    }
                case ElementId.Obstacle:
                    {
                        return GetObstacleImage(element);
                    }
                case ElementId.Bonus:
                    {
                        return GetBonusImage(element);
                    }
                case ElementId.Dead:
                    {
                        return GetDeadImage(element);
                    }
                default:
                    {
                        return null;
                    }
            }
        }
        private Bitmap GetAnimation(Element element)
        {
            switch (element.ElementId)
            {
                case ElementId.Bullet:
                    {
                        return GetAnimationBulletImage(element);
                    }

            }
            return null;
        }
        private Bitmap GetHeroImage(Element element)
        {
            Hero hero = element as Hero;
            if (hero.Angle != null)
                return RotateImage(MakeTransparent( heroDictionary[hero.HeroId],tranparencyColor), (int)hero.Angle);
            return MakeTransparent(heroDictionary[hero.HeroId], tranparencyColor);
        }
        private Bitmap GetEnemyImage(Element element)
        {
            Enemy enemy = element as Enemy;
                if (enemy.Angle != null)
                    return RotateImage(MakeTransparent(enemyDictionary[enemy.EnemyId], tranparencyColor),
                                       (int) enemy.Angle);
                return MakeTransparent(enemyDictionary[enemy.EnemyId], tranparencyColor);
           
        }
        private Bitmap GetBulletImage(Element element)
        {
            Bullet bullet = element as Bullet;
            if (bullet.Angle != null)
                return RotateImage(MakeTransparent(bulletDictionary[bullet.BulletId], tranparencyColor),
                                   (int) bullet.Angle);
            return MakeTransparent(bulletDictionary[bullet.BulletId], tranparencyColor);

        }
        private Bitmap GetObstacleImage(Element element)
        {
            Obstacle obstacle = element as Obstacle;
            if (obstacle.Angle != null)
                return RotateImage(MakeTransparent(obstacleDictionary[obstacle.ObstacleId], tranparencyColor),
                                   (int)obstacle.Angle);
            return MakeTransparent(obstacleDictionary[obstacle.ObstacleId], tranparencyColor);

        }
        private Bitmap GetBonusImage(Element element)
        {
            Bonus bonus = element as Bonus;
            if (bonus.Angle != null)
                return RotateImage(MakeTransparent(bonusDictionary[bonus.BonusID], tranparencyColor),
                                   (int)bonus.Angle);
            return MakeTransparent(bonusDictionary[bonus.BonusID], tranparencyColor);

        }
        private Bitmap GetDeadImage(Element element)
        {
            DeadElement deadElement = element as DeadElement;
            if (deadElement.Angle != null)
                return RotateImage(MakeTransparent(deadDictionary[deadElement.DeadId], tranparencyColor),
                                   (int)deadElement.Angle);
            return MakeTransparent(deadDictionary[deadElement.DeadId], tranparencyColor);

        }
        public Bitmap GetWeaponImage(BulletId bulletId)
        {
            return MakeTransparent( weaponDictionary[bulletId],tranparencyColor);
        }
        public void SetSize(Element element)
        {
            Bitmap bitmap = GetBitmap(element);
            element.Width = bitmap.Width;
            element.Height = bitmap.Height;
        }
        private Bitmap GetAnimationBulletImage(Element element)
        {
            Bullet bullet = element as Bullet;
            if (bullet.Angle != null)
                return
                    RotateImage(
                        MakeTransparent(bulletAnimationDictionary[bullet.BulletId][bullet.AnimationCount],
                                        tranparencyColor), (int) bullet.Angle);
            return MakeTransparent(bulletAnimationDictionary[bullet.BulletId][bullet.AnimationCount],tranparencyColor);
        }
        /// <summary>
        /// Zwraca maxymalna liczbe klatek animacji w zaleznosci od ID
        /// </summary>
        /// <param name="element">Element</param>
        /// <returns>Liczba klatek animacji</returns>
        public int GetAnimationCount(Element element)
        {
            switch(element.ElementId)
            {
                case ElementId.Bullet:
                    {
                        Bullet bullet = element as Bullet;
                        return bulletAnimationDictionary[bullet.BulletId].Count;
                    }
                default:
                    {
                        return 0;
                    }
            }
        }
    }
}
